{"componentChunkName":"component---src-templates-blog-post-blog-post-js","path":"/articulos/css-moderno-2026-sin-javascript/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"CSS moderno en 2026: cosas para las que ya no necesitas JavaScript\",\n  \"seoTitle\": \"CSS moderno en 2026: menos JavaScript para tu interfaz\",\n  \"date\": \"2026-08-31\",\n  \"description_sort\": \"Selectores, Container Queries, nesting y animaciones CSS que reducen JavaScript en interfaces modernas.\",\n  \"description\": \"CSS ha evolucionado enormemente. Descubre qué problemas que antes resolvíamos con JavaScript ya pueden implementarse con CSS moderno: :has(), nesting, container queries, animaciones y mucho más.\",\n  \"featuredImage\": \"css-moderno-2026-portada.webp\",\n  \"twitterUsername\": \"@CursosDesarrol1\",\n  \"tags\": [\"css\", \"css-moderno\", \"frontend\", \"javascript\", \"responsive-design\", \"web-platform\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"span\", {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1200px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/0947858ba5689735983adb34bbfe79f3/a8642/css-moderno-2026-portada.webp\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"66.66666666666666%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/webp;base64,UklGRogAAABXRUJQVlA4IHwAAADQAwCdASoUAA0APtFUo0uoJKMhsAgBABoJaACdMoAC8JzXNAK7CAAA/vRWHJcSvrsEMcRHIEywMKmFJ060hT2RRTVabB2NTf16X5IiV8f4QYBPFmiN2tfG1FL5i31LWbp2BbTBbp7MJUTMibnv20ZLR/tiYv1VIvdy6AAA')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Desarrollador observando componentes web responsive que se adaptan con CSS moderno\",\n    \"title\": \"Desarrollador observando componentes web responsive que se adaptan con CSS moderno\",\n    \"src\": \"/static/0947858ba5689735983adb34bbfe79f3/5bb53/css-moderno-2026-portada.webp\",\n    \"srcSet\": [\"/static/0947858ba5689735983adb34bbfe79f3/cb58d/css-moderno-2026-portada.webp 300w\", \"/static/0947858ba5689735983adb34bbfe79f3/f8b1b/css-moderno-2026-portada.webp 600w\", \"/static/0947858ba5689735983adb34bbfe79f3/5bb53/css-moderno-2026-portada.webp 1200w\", \"/static/0947858ba5689735983adb34bbfe79f3/a8642/css-moderno-2026-portada.webp 1536w\"],\n    \"sizes\": \"(max-width: 1200px) 100vw, 1200px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), mdx(\"br\", null), mdx(\"br\", null), mdx(\"h1\", null, \"CSS moderno en 2026: cosas para las que ya no necesitas JavaScript\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"CSS ha evolucionado enormemente. Muchas tareas que antes resolv\\xEDamos con JavaScript, librer\\xEDas externas o trucos de maquetaci\\xF3n ya forman parte de la plataforma web.\")), mdx(\"p\", null, \"Durante muchos a\\xF1os el reparto de responsabilidades en una aplicaci\\xF3n web parec\\xEDa bastante claro: HTML defin\\xEDa la estructura, CSS se encargaba de la apariencia y JavaScript proporcionaba el comportamiento.\"), mdx(\"p\", null, \"Era una simplificaci\\xF3n \\xFAtil, pero cada vez representa peor la realidad. Selectores capaces de reaccionar al contenido, consultas basadas en el tama\\xF1o de un componente, CSS anidado, animaciones vinculadas al scroll o elementos posicionados respecto a otros elementos de la interfaz son algunos ejemplos.\"), mdx(\"p\", null, \"CSS ya no es simplemente el lenguaje que utilizamos para cambiar colores y m\\xE1rgenes. En 2026 merece la pena revisar qu\\xE9 significa realmente conocer CSS moderno.\"), mdx(\"h2\", null, \"El problema de aprender CSS hace unos a\\xF1os\"), mdx(\"p\", null, \"Imaginemos que aprendimos desarrollo web alrededor de 2018. Probablemente nuestra caja de herramientas inclu\\xEDa Flexbox, Grid, Media Queries, Sass y JavaScript para manipular clases.\"), mdx(\"p\", null, \"Con eso pod\\xEDamos construir pr\\xE1cticamente cualquier interfaz. Y todav\\xEDa podemos hacerlo. El problema es continuar desarrollando exactamente de esa manera e ignorar una parte importante de la evoluci\\xF3n reciente del navegador.\"), mdx(\"p\", null, \"Un ejemplo sencillo es Sass. Durante a\\xF1os una de las razones para utilizar un preprocesador era poder escribir estilos anidados:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.card {\\n    padding: 20px;\\n\\n    .title {\\n        font-size: 24px;\\n    }\\n\\n    &:hover {\\n        transform: translateY(-2px);\\n    }\\n}'), mdx(\"p\", null, \"Hoy podemos utilizar esa sintaxis mediante CSS Nesting nativo. No significa que Sass haya dejado de tener utilidad; significa que una de las razones hist\\xF3ricas para introducirlo en un proyecto ha desaparecido.\"), mdx(\"h2\", null, \"1. \", \"`\", \":has()\", \"`\", \": CSS puede mirar dentro de un elemento\"), mdx(\"p\", null, \"Durante a\\xF1os los selectores CSS funcionaban fundamentalmente en una direcci\\xF3n: seleccion\\xE1bamos un elemento y despu\\xE9s sus descendientes.\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.card img {\\n    width: 100%;\\n}'), mdx(\"p\", null, \"El problema aparec\\xEDa cuando necesit\\xE1bamos hacer lo contrario. Por ejemplo, aplicar un estilo diferente a una tarjeta solamente cuando contiene una imagen. Antes era habitual a\\xF1adir una clase desde el servidor o inspeccionar el DOM con JavaScript.\"), mdx(\"p\", null, \"Con \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has\"\n  }, \"`\", \":has()\", \"`\"), \" podemos expresarlo directamente:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, \".card:has(> img) {\\n    padding-top: 0;\\n}\"), mdx(\"p\", null, \"Estamos diciendo: selecciona \", \"`\", \".card\", \"`\", \" cuando tenga una imagen como hijo directo. Tambi\\xE9n podemos reaccionar al estado de un formulario o a elementos como un descuento:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, 'form:has(input:invalid) button[type=\"submit\"] {\\n    opacity: 0.5;\\n}\\n\\n.product:has(.discount) {\\n    border: 2px solid currentColor;\\n}'), mdx(\"p\", null, \"`\", \":has()\", \"`\", \" est\\xE1 ampliamente disponible, pero no conviene anclarlo a selectores demasiado generales como \", \"`\", \"body\", \"`\", \" o \", \"`\", \":root\", \"`\", \". Mantener el contenedor y el selector interno acotados ayuda al navegador a reevaluar los cambios de forma eficiente.\"), mdx(\"h2\", null, \"2. Container Queries: componentes que conocen su propio tama\\xF1o\"), mdx(\"p\", null, \"Las Media Queries cambiaron completamente el desarrollo responsive, pero preguntan por el tama\\xF1o del \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"viewport\"), \". Eso funciona bien cuando dise\\xF1amos una p\\xE1gina y peor cuando dise\\xF1amos un componente reutilizable.\"), mdx(\"p\", null, \"Una tarjeta puede aparecer ocupando toda la pantalla, dentro de una columna, en un \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"sidebar\"), \" o en un dashboard. Su comportamiento deber\\xEDa depender del espacio disponible, no \\xFAnicamente del tama\\xF1o de la ventana.\"), mdx(\"p\", null, \"Aqu\\xED entran las \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container\"\n  }, \"Container Queries\"), \". Declaramos un contenedor y consultamos su tama\\xF1o:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.products {\\n    container-type: inline-size;\\n}\\n\\n@container (min-width: 600px) {\\n    .product-card {\\n        display: grid;\\n        grid-template-columns: 200px 1fr;\\n    }\\n}'), mdx(\"p\", null, \"Ahora el componente responde al tama\\xF1o de su contenedor. Esta diferencia cambia la forma de dise\\xF1ar componentes para React, Angular, Vue o Web Components.\"), mdx(\"span\", {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1200px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/4b4d944a2277666c22578ae4736959cb/a8642/css-moderno-2026-componentes.webp\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"66.66666666666666%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/webp;base64,UklGRmoAAABXRUJQVlA4IF4AAADQAwCdASoUAA0APtFUo0uoJKMhsAgBABoJYgCdMoADAXuUJDUjGAAA/vaT5p9Jit9TCwMSD1BMAvgC7EMX/PbwjJS3yUcpVnAh/ZBh3naJoIfY7Jx4NieYBQVYAAAA')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Una tarjeta de producto que reorganiza su contenido en distintos tamaños de contenedor\",\n    \"title\": \"Una tarjeta de producto que reorganiza su contenido en distintos tamaños de contenedor\",\n    \"src\": \"/static/4b4d944a2277666c22578ae4736959cb/5bb53/css-moderno-2026-componentes.webp\",\n    \"srcSet\": [\"/static/4b4d944a2277666c22578ae4736959cb/cb58d/css-moderno-2026-componentes.webp 300w\", \"/static/4b4d944a2277666c22578ae4736959cb/f8b1b/css-moderno-2026-componentes.webp 600w\", \"/static/4b4d944a2277666c22578ae4736959cb/5bb53/css-moderno-2026-componentes.webp 1200w\", \"/static/4b4d944a2277666c22578ae4736959cb/a8642/css-moderno-2026-componentes.webp 1536w\"],\n    \"sizes\": \"(max-width: 1200px) 100vw, 1200px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), mdx(\"h2\", null, \"3. CSS Nesting: menos necesidad de preprocesadores\"), mdx(\"p\", null, \"CSS Nesting permite estructurar los estilos alrededor del componente sin repetir selectores constantemente:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.navigation {\\n    display: flex;\\n    gap: 1rem;\\n\\n    a {\\n        text-decoration: none;\\n\\n        &:hover {\\n            text-decoration: underline;\\n        }\\n    }\\n}'), mdx(\"p\", null, \"No hay nada incorrecto en escribir \", \"`\", \".navigation a\", \"`\", \" y \", \"`\", \".navigation a:hover\", \"`\", \" como reglas independientes. Sin embargo, el nesting hace m\\xE1s evidente la relaci\\xF3n entre los elementos. Su sintaxis y especificidad tienen matices frente a los preprocesadores, por lo que merece la pena consultar la \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Nesting\"\n  }, \"gu\\xEDa de CSS Nesting\"), \" antes de migrar reglas complejas.\"), mdx(\"h2\", null, \"4. Animaciones vinculadas al scroll sin escuchar \", \"`\", \"scroll\", \"`\"), mdx(\"p\", null, \"Un patr\\xF3n cl\\xE1sico del frontend consiste en ejecutar una animaci\\xF3n conforme el usuario se desplaza por la p\\xE1gina. Durante a\\xF1os eso significaba un listener, c\\xE1lculos de posici\\xF3n y actualizaciones de estilos desde JavaScript.\"), mdx(\"p\", null, \"Las \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Scroll-driven_animations\"\n  }, \"scroll-driven animations\"), \" permiten vincular una animaci\\xF3n CSS al desplazamiento:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.progress {\\n    animation-name: grow;\\n    animation-duration: 1ms;\\n    animation-timeline: scroll();\\n}\\n\\n@keyframes grow {\\n    from { transform: scaleX(0); }\\n    to { transform: scaleX(1); }\\n}'), mdx(\"p\", null, \"El navegador relaciona la animaci\\xF3n con el scroll sin un listener ejecut\\xE1ndose continuamente. El valor de duraci\\xF3n distinto de cero mantiene un comportamiento consistente en navegadores que lo necesitan. JavaScript sigue siendo \\xFAtil para interacciones complejas, pero una categor\\xEDa completa de efectos puede resolverse de forma declarativa.\"), mdx(\"h2\", null, \"5. Anchor Positioning: tooltips y popovers con CSS\"), mdx(\"p\", null, \"Colocar un tooltip, un men\\xFA o un selector respecto a un bot\\xF3n ha generado miles de l\\xEDneas de JavaScript: posiciones, l\\xEDmites de pantalla, desplazamiento, redimensionamiento y capas superpuestas.\"), mdx(\"p\", null, \"CSS Anchor Positioning traslada parte de esa responsabilidad al navegador. Podemos declarar un ancla y posicionar otro elemento respecto a ella:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '.button {\\n    anchor-name: --menu-button;\\n}\\n\\n.menu {\\n    position: absolute;\\n    position-anchor: --menu-button;\\n    top: anchor(bottom);\\n    left: anchor(left);\\n}'), mdx(\"p\", null, \"El men\\xFA queda vinculado al bot\\xF3n. Esta funcionalidad es Baseline reci\\xE9n disponible en 2026, as\\xED que antes de adoptarla conviene revisar el p\\xFAblico del proyecto, probar los navegadores objetivo y mantener un fallback cuando sea necesario.\"), mdx(\"span\", {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1200px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/2d44a9f285e53bf1d79dd535cf6798d8/a8642/css-moderno-2026-anclas-scroll.webp\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"66.66666666666666%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/webp;base64,UklGRl4AAABXRUJQVlA4IFIAAABwAwCdASoUAA0APtFUo0uoJKMhsAgBABoJYgCdMoAGjuGRaAAA/vFkczvJ4Rth1WGBeHDkXsEwLJDD5FfZvjUr9qVaKsij+DF9dLPdblTfBAAA')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Tooltip y panel flotante anclados a controles de interfaz junto a una animación guiada por scroll\",\n    \"title\": \"Tooltip y panel flotante anclados a controles de interfaz junto a una animación guiada por scroll\",\n    \"src\": \"/static/2d44a9f285e53bf1d79dd535cf6798d8/5bb53/css-moderno-2026-anclas-scroll.webp\",\n    \"srcSet\": [\"/static/2d44a9f285e53bf1d79dd535cf6798d8/cb58d/css-moderno-2026-anclas-scroll.webp 300w\", \"/static/2d44a9f285e53bf1d79dd535cf6798d8/f8b1b/css-moderno-2026-anclas-scroll.webp 600w\", \"/static/2d44a9f285e53bf1d79dd535cf6798d8/5bb53/css-moderno-2026-anclas-scroll.webp 1200w\", \"/static/2d44a9f285e53bf1d79dd535cf6798d8/a8642/css-moderno-2026-anclas-scroll.webp 1536w\"],\n    \"sizes\": \"(max-width: 1200px) 100vw, 1200px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), mdx(\"h2\", null, \"6. View Transitions: transiciones entre vistas\"), mdx(\"p\", null, \"La View Transition API permite que el navegador gestione la transici\\xF3n visual entre estados. En una SPA, JavaScript todav\\xEDa inicia el cambio de DOM:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, 'document.startViewTransition(() => {\\n    updateDOM();\\n});'), mdx(\"p\", null, \"Pero la apariencia se define en CSS:\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, '::view-transition-old(root) {\\n    animation: fade-out 0.2s;\\n}\\n\\n::view-transition-new(root) {\\n    animation: fade-in 0.2s;\\n}'), mdx(\"p\", null, \"En navegaciones entre documentos del mismo origen tambi\\xE9n es posible activar transiciones mediante \", \"`\", \"@view-transition\", \"`\", \". La idea importante es distinguir el comportamiento de aplicaci\\xF3n \\u2014que puede seguir necesitando JavaScript\\u2014 de una transici\\xF3n visual que el navegador ya conoce y puede animar. Consulta la \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API\"\n  }, \"View Transition API\"), \" antes de usarla en producci\\xF3n.\"), mdx(\"h2\", null, \"7. CSS tambi\\xE9n empieza a tomar decisiones\"), mdx(\"p\", null, \"Funciones como \", \"`\", \"clamp()\", \"`\", \", \", \"`\", \"min()\", \"`\", \", \", \"`\", \"max()\", \"`\", \" y \", \"`\", \"calc()\", \"`\", \" permiten expresar relaciones que antes requer\\xEDan m\\xFAltiples Media Queries o c\\xE1lculos adicionales.\"), mdx(CodeJs, {\n    mdxType: \"CodeJs\"\n  }, 'h1 {\\n    font-size: clamp(2rem, 5vw, 5rem);\\n}\\n\\n.container {\\n    width: min(1200px, 90vw);\\n}'), mdx(\"p\", null, \"Son herramientas peque\\xF1as individualmente. Juntas permiten construir sistemas responsive mucho m\\xE1s declarativos.\"), mdx(\"h2\", null, \"8. \\xBFSignifica todo esto que necesitamos menos JavaScript?\"), mdx(\"p\", null, \"En determinadas interfaces, s\\xED. Pero CSS no sustituye a JavaScript. Seguimos necesit\\xE1ndolo para l\\xF3gica de negocio, llamadas a API, gesti\\xF3n compleja de estado, manipulaci\\xF3n de datos, autenticaci\\xF3n, comunicaciones en tiempo real e interacci\\xF3n avanzada.\"), mdx(\"p\", null, \"Lo que est\\xE1 cambiando es la frontera. Hay comportamientos de presentaci\\xF3n que durante a\\xF1os trasladamos a JavaScript simplemente porque CSS no ten\\xEDa capacidad para resolverlos. Eliminar ese JavaScript innecesario suele significar menos c\\xF3digo, menos dependencias, menos estados que sincronizar y menos posibilidades de introducir errores.\"), mdx(\"h2\", null, \"9. El navegador se est\\xE1 convirtiendo en un framework m\\xE1s potente\"), mdx(\"p\", null, \"Durante buena parte de la historia del frontend, las librer\\xEDas evolucionaron m\\xE1s r\\xE1pido que la plataforma. Cuando el navegador no ofrec\\xEDa algo, JavaScript lo solucionaba. Necesit\\xE1bamos variables y nesting: utiliz\\xE1bamos preprocesadores. Necesit\\xE1bamos mejores selectores: utiliz\\xE1bamos JavaScript.\"), mdx(\"p\", null, \"Pero la plataforma web aprende. Las soluciones \\xFAtiles durante a\\xF1os terminan, en algunos casos, convirti\\xE9ndose en est\\xE1ndares. Un desarrollador frontend que solo aprende un framework corre el riesgo de mantener soluciones creadas para limitaciones que ya no existen.\"), mdx(\"h2\", null, \"10. Baseline: c\\xF3mo saber si podemos utilizar una caracter\\xEDstica\"), mdx(\"p\", null, \"CSS evoluciona tan r\\xE1pidamente que es dif\\xEDcil saber qu\\xE9 podemos utilizar realmente. Una caracter\\xEDstica puede existir en la especificaci\\xF3n sin estar disponible para todos los usuarios.\"), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Glossary/Baseline/Compatibility\"\n  }, \"Web Platform Baseline\"), \" resume la disponibilidad de funcionalidades en los navegadores principales como \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Limited Availability\"), \", \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Newly Available\"), \" o \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Widely Available\"), \". No sustituye las pruebas ni define por s\\xED sola la compatibilidad de un proyecto, pero ayuda a tomar decisiones sin memorizar versiones concretas de cada navegador.\"), mdx(\"p\", null, \"Conocer CSS moderno no consiste en usar siempre lo m\\xE1s nuevo. Consiste en saber cu\\xE1ndo una caracter\\xEDstica aporta valor, qu\\xE9 audiencia necesita soporte y cu\\xE1l es el fallback adecuado.\"), mdx(\"h2\", null, \"\\xBFSigue teniendo sentido aprender CSS en profundidad?\"), mdx(\"p\", null, \"Precisamente ahora tiene m\\xE1s sentido. Los frameworks pueden abstraer parte del desarrollo frontend, pero todos terminan ejecut\\xE1ndose sobre las capacidades del navegador.\"), mdx(\"p\", null, \"Un desarrollador que comprende bien CSS puede distinguir entre un problema que necesita JavaScript y uno que el navegador ya sabe resolver. Esa diferencia puede evitar dependencias y simplificar considerablemente una aplicaci\\xF3n.\"), mdx(\"h2\", null, \"Conclusi\\xF3n\"), mdx(\"p\", null, \"CSS est\\xE1 incorporando algunas de las mejoras m\\xE1s importantes de su historia. \", \"`\", \":has()\", \"`\", \" permite construir relaciones entre elementos que antes eran dif\\xEDciles de expresar. Container Queries hacen que los componentes respondan a su propio contexto. CSS Nesting reduce una de las razones tradicionales para utilizar preprocesadores. Las animaciones vinculadas al scroll y Anchor Positioning trasladan trabajo al navegador.\"), mdx(\"p\", null, \"La consecuencia no es que JavaScript vaya a desaparecer. Es algo m\\xE1s sencillo: \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"la plataforma web puede hacer cada vez m\\xE1s cosas por s\\xED sola\"), \".\"), mdx(\"p\", null, \"Antes de instalar otra dependencia o escribir otro listener de JavaScript, quiz\\xE1 deber\\xEDamos preguntarnos si el navegador ya sabe hacerlo.\"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"twitterUsername":"@CursosDesarrol1","title":"CSS moderno en 2026: cosas para las que ya no necesitas JavaScript","seoTitle":"CSS moderno en 2026: menos JavaScript para tu interfaz","date":"2026-08-31","description":"CSS ha evolucionado enormemente. Descubre qué problemas que antes resolvíamos con JavaScript ya pueden implementarse con CSS moderno: :has(), nesting, container queries, animaciones y mucho más.","featuredImage":{"childImageSharp":{"fluid":{"base64":"data:image/webp;base64,UklGRogAAABXRUJQVlA4IHwAAADQAwCdASoUAA0APtFUo0uoJKMhsAgBABoJaACdMoAC8JzXNAK7CAAA/vRWHJcSvrsEMcRHIEywMKmFJ060hT2RRTVabB2NTf16X5IiV8f4QYBPFmiN2tfG1FL5i31LWbp2BbTBbp7MJUTMibnv20ZLR/tiYv1VIvdy6AAA","aspectRatio":1.5037593984962405,"src":"/static/0947858ba5689735983adb34bbfe79f3/ccdb5/css-moderno-2026-portada.webp","srcSet":"/static/0947858ba5689735983adb34bbfe79f3/6b183/css-moderno-2026-portada.webp 200w,\n/static/0947858ba5689735983adb34bbfe79f3/fc32b/css-moderno-2026-portada.webp 400w,\n/static/0947858ba5689735983adb34bbfe79f3/ccdb5/css-moderno-2026-portada.webp 800w,\n/static/0947858ba5689735983adb34bbfe79f3/9000d/css-moderno-2026-portada.webp 1200w,\n/static/0947858ba5689735983adb34bbfe79f3/7dd62/css-moderno-2026-portada.webp 1536w","sizes":"(max-width: 800px) 100vw, 800px"}}}}}},"pageContext":{"slug":"/articulos/css-moderno-2026-sin-javascript/","previous":{"fields":{"slug":"/avisos_legales/politica_cookies/"}},"next":null}},"staticQueryHashes":["2032873950"]}